home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 1.iso / icons / animator.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-04-16  |  16KB  |  606 lines

  1. #include "animator.h"
  2. #include <string.h>
  3.  
  4. VOID NEAR PASCAL ParseCmdLine (LPSTR);
  5.  
  6. //////////////////////////////////////////////////////////////////////////
  7. //  WinMain - Obviously sets up the Window class, loads string
  8. //            and menu resources, creates the frame window,
  9. //            sets the timer function pointer, toolhelp notify,
  10. //            and allows the non-preemted loop to start.
  11. //////////////////////////////////////////////////////////////////////////
  12.  
  13. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
  14.     LPSTR lpszCmdLine, int nCmdShow)
  15. {
  16.     HACCEL      hAccel;
  17.     WNDCLASS    wndclass;
  18.     MSG         msg;
  19.  
  20.     if ((short)GetVersion() < 0x0310)
  21.     {
  22.         MESSAGE (IDS_WinVer);
  23.         return 0;
  24.     }
  25.  
  26.     _hInst = hInst;
  27.  
  28.     // Load all application strings... (defined in .RC file)
  29.     LoadStr (IDS_AppName, _szAppName);
  30.     LoadStr (IDS_AppTitle, _szTitleBar);
  31.     LoadStr (IDS_ChildClassName, _szChildClass);
  32.     LoadStr (IDS_StatBarClassName, _szStatBarClass);
  33.     LoadStr (IDS_Extension, _szExtension);
  34.     LoadStr (IDS_Untitled, _szUntitled);
  35.     LoadStr (IDS_TimerIntervalKey, _szTimeInt);
  36.     LoadStr (IDS_InfoSection, _szInfo);
  37.     LoadStr (IDS_NumIconsKey, _szNumIcons);
  38.     LoadStr (IDS_LinkFileKey, _szLinkFile);
  39.     LoadStr (IDS_IconsSection, _szIconSection); 
  40.     LoadStr (IDS_IconFrameKey, _szIcon);
  41.     LoadStr (IDS_AutoAnimateKey, _szAutoAnimateKey);
  42.  
  43.     if (hPrevInst)
  44.     {
  45.         HWND hwnd = FindWindow (_szAppName,NULL);
  46.         BringWindowToTop (hwnd);
  47.         return 0;
  48.     }
  49.  
  50.     _hmenuMain        = LoadMenu(_hInst, MAINMENU);
  51.     _hmenuChild       = LoadMenu(_hInst, CHILDMENU);
  52.     _hmenuMainWindow  = 
  53.     _hmenuChildWindow = GetSubMenu(_hmenuChild, WNDMENUPOS);
  54.  
  55.     _hpnBlack = CreatePen (PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
  56.     _hpnGray  = CreatePen (PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
  57.     _hpnWhite = CreatePen (PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
  58.  
  59.     if (!hPrevInst) 
  60.     {
  61.         wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  62.         wndclass.lpfnWndProc    = FrameProc;
  63.         wndclass.cbClsExtra     = 0;
  64.         wndclass.cbWndExtra     = 0;
  65.         wndclass.hInstance      = _hInst;
  66.         wndclass.hIcon          = LoadIcon(_hInst, MAINICON);
  67.         wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  68.         wndclass.hbrBackground  = COLOR_APPWORKSPACE + 1;
  69.         wndclass.lpszMenuName   = NULL;
  70.         wndclass.lpszClassName  = _szAppName;
  71.  
  72.         if (!RegisterClass(&wndclass)) return 0;
  73.  
  74.         wndclass.lpfnWndProc    = ChildProc;
  75.         wndclass.cbWndExtra     = WW_ENDOFWORDS;
  76.         wndclass.hIcon          = LoadIcon(_hInst, CHILDICON);
  77.         wndclass.hbrBackground  = COLOR_WINDOW + 1;
  78.         wndclass.lpszClassName  = _szChildClass;
  79.         
  80.         if (!RegisterClass(&wndclass)) return 0;
  81.  
  82.         wndclass.lpfnWndProc    = StatusBarProc;
  83.         wndclass.cbWndExtra     = 0;
  84.         wndclass.hIcon          = NULL;
  85.         wndclass.hbrBackground  = COLOR_BTNFACE + 1;
  86.         wndclass.lpszClassName  = _szStatBarClass;
  87.  
  88.         if (!RegisterClass (&wndclass)) return 0;
  89.     }
  90.  
  91.     _lpfnTimer = MakeProcInstance ((FARPROC)TimerCallback, _hInst);
  92.     if (_lpfnTimer == NULL) goto MErr0;
  93.  
  94.     _lpfnNotify = MakeProcInstance ((FARPROC)NotifyProc, _hInst);
  95.     if (_lpfnNotify == NULL) goto MErr1;
  96.  
  97.     _lpfnSettings = MakeProcInstance ((FARPROC)SettingsDlg, _hInst);
  98.     if (_lpfnSettings == NULL) goto MErr2;
  99.  
  100.     _lpfnAbout = MakeProcInstance ((FARPROC)About, _hInst);
  101.     if (_lpfnAbout == NULL) goto MErr3;
  102.  
  103.     _lpfnBroadcast = MakeProcInstance ((FARPROC)BroadcastProc, _hInst);
  104.     if (_lpfnBroadcast == NULL) goto MErr4;
  105.  
  106.     _hwndFrame = CreateWindow(_szAppName, _szTitleBar,
  107.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  108.         0, 0, FRAME_X, FRAME_Y,
  109.         NULL, _hmenuMain, _hInst, NULL);
  110.  
  111.     if (!IsWindow(_hwndFrame)) goto MErr5;
  112.  
  113.     if (!RestorePosition (_hwndFrame, nCmdShow)) 
  114.     {
  115.         CenterWindow (_hwndFrame);
  116.     }
  117.     
  118.     if (lpszCmdLine)
  119.     {
  120.         ParseCmdLine (lpszCmdLine);
  121.         RefreshAnimations ();
  122.     }
  123.  
  124.     ShowWindow(_hwndFrame, SW_SHOW);
  125.     UpdateWindow(_hwndFrame);
  126.     
  127.     hAccel = LoadAccelerators(_hInst, ACCELTABLE);
  128.     if (hAccel == NULL) goto MErr5;
  129.  
  130.     while (GetMessage(&msg, NULL, 0, 0))
  131.     {
  132.         if (!TranslateMDISysAccel(_hwndClient, &msg) &&
  133.             !TranslateAccelerator(_hwndFrame, hAccel, &msg)) 
  134.         {
  135.             TranslateMessage(&msg);
  136.             DispatchMessage(&msg);
  137.         }
  138.     }
  139.  
  140. MErr5:
  141.     FreeProcInstance (_lpfnBroadcast);
  142. MErr4:
  143.     FreeProcInstance (_lpfnAbout);
  144. MErr3:
  145.     FreeProcInstance (_lpfnSettings);
  146. MErr2:
  147.     FreeProcInstance (_lpfnNotify);
  148. MErr1:
  149.     FreeProcInstance (_lpfnTimer);    
  150. MErr0:
  151.     DeletePen (_hpnBlack);
  152.     DeletePen (_hpnWhite);
  153.     DeletePen (_hpnGray);
  154.  
  155.     return msg.wParam;
  156. }
  157.  
  158.  
  159.  
  160. //////////////////////////////////////////////////////////////////////////
  161. // CenterWindow - takes any window (more especially dialog boxes) and
  162. //                centers it on the display.
  163. //////////////////////////////////////////////////////////////////////////
  164.  
  165. VOID WINAPI CenterWindow (HWND hDlg)
  166. {
  167.   RECT rc;
  168.  
  169.   GetWindowRect(hDlg,&rc);
  170.   SetWindowPos(hDlg,NULL,
  171.    (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
  172.    (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
  173.     0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  174. }
  175.  
  176.  
  177.  
  178. //////////////////////////////////////////////////////////////////////////
  179. // RestorePosition() - Gets the formated information for the 
  180. // WINDOWPLACEMENT structure from the WIN.INI file, parses it by
  181. // calling IntFromString(), and then calls SetWindowPlacement().
  182. //////////////////////////////////////////////////////////////////////////
  183.  
  184. BOOL WINAPI RestorePosition (HWND hwnd, short nCmdShow)
  185. {
  186.     char szFmt[80];
  187.     LPSTR lpszCur = (LPSTR)szFmt;
  188.     WINDOWPLACEMENT wpl;
  189.  
  190.     GetProfileString ((LPSTR)_szTitleBar, (LPSTR)"Position\0", (LPSTR)"\0",
  191.         (LPSTR)szFmt, sizeof(szFmt));
  192.  
  193.     if (szFmt[0] == '\0' || IntFromString((LPSTR FAR *)&lpszCur) != 9)
  194.     {
  195.         return FALSE;
  196.     }
  197.     else
  198.     {
  199.         // Format in the WIN.INI file for the position restoration is:
  200.         // [Animator]
  201.         // Position = 9 showcmd minX minY maxX maxY normX normY normDX normDY
  202.         //
  203.         wpl.length = sizeof(wpl); 
  204.         wpl.showCmd = (UINT)IntFromString((LPSTR FAR *)&lpszCur);
  205.         wpl.showCmd = (UINT)nCmdShow;
  206.         wpl.ptMinPosition.x = IntFromString((LPSTR FAR *)&lpszCur);
  207.         wpl.ptMinPosition.y = IntFromString((LPSTR FAR *)&lpszCur);
  208.         wpl.ptMaxPosition.x = IntFromString((LPSTR FAR *)&lpszCur);
  209.         wpl.ptMaxPosition.y = IntFromString((LPSTR FAR *)&lpszCur);
  210.         wpl.rcNormalPosition.left = IntFromString((LPSTR FAR *)&lpszCur);
  211.         wpl.rcNormalPosition.top = IntFromString((LPSTR FAR *)&lpszCur);
  212.         wpl.rcNormalPosition.right = IntFromString((LPSTR FAR *)&lpszCur);
  213.         wpl.rcNormalPosition.bottom = IntFromString((LPSTR FAR *)&lpszCur);
  214.  
  215.         return SetWindowPlacement(hwnd, &wpl);
  216.     }
  217. }
  218.  
  219.  
  220.  
  221. //////////////////////////////////////////////////////////////////////////
  222. // RecordPosition() - Gets the window placement and show state, by
  223. // using the GetWindowPlacement function.  the length member MUST
  224. // be filled or it will fail.  We then write the information to 
  225. // the WIN.INI with the info separated by spaces.
  226. //////////////////////////////////////////////////////////////////////////
  227.  
  228. VOID WINAPI RecordPosition(HWND hwnd)
  229. {
  230.     WINDOWPLACEMENT wpl;
  231.  
  232.     char szFmt[80];
  233.  
  234.     wpl.length = sizeof(wpl);    // necessary...
  235.     GetWindowPlacement(hwnd, &wpl);
  236.  
  237.     wsprintf((LPSTR)szFmt, "%d %d %d %d %d %d %d %d %d %d",
  238.         9,
  239.         wpl.showCmd,
  240.         wpl.ptMinPosition.x,
  241.         wpl.ptMinPosition.y,
  242.         wpl.ptMaxPosition.x,
  243.         wpl.ptMaxPosition.y,
  244.         wpl.rcNormalPosition.left,
  245.         wpl.rcNormalPosition.top,
  246.         wpl.rcNormalPosition.right,
  247.         wpl.rcNormalPosition.bottom
  248.     );
  249.  
  250.     WriteProfileString((LPSTR)_szTitleBar, (LPSTR)"Position", (LPSTR)szFmt);
  251. }
  252.  
  253.  
  254.  
  255. //////////////////////////////////////////////////////////////////////////
  256. // IntFromString() - Our version of the C function itoa, with a little
  257. // more flexibility given our situation: a string of ints separated by
  258. // spaces.
  259. //////////////////////////////////////////////////////////////////////////
  260.  
  261. short WINAPI IntFromString(LPSTR FAR * lplpsz)
  262. {
  263.     LPSTR lpsz = *lplpsz;
  264.     short i = 0;
  265.     char ch;
  266.     BOOL fNeg;
  267.  
  268.     while (*lpsz == ' ')
  269.         lpsz++;
  270.  
  271.     fNeg = FALSE;
  272.     while (ch = *lpsz++)
  273.     {
  274.         if (ch == '-')
  275.         {
  276.             fNeg = !fNeg;
  277.             continue;
  278.         }
  279.  
  280.         if (ch < '0' || ch > '9')
  281.             break;
  282.         i = (i * 10) + (ch - '0');
  283.     }
  284.     *lplpsz = lpsz;
  285.  
  286.     return (fNeg ? -i : i);
  287. }
  288.  
  289.  
  290.  
  291. //////////////////////////////////////////////////////////////////////////
  292. // DeletePreviousHandles - Frees the memory occupied by the icons
  293. // in the list, if any in the list.
  294. //////////////////////////////////////////////////////////////////////////
  295.  
  296. VOID WINAPI DeletePreviousHandles (HWND hwnd)
  297. {
  298.     short sChild = WINDOWNUM(hwnd);
  299.     short sLimit = NUMICONS (sChild);
  300.     short i;
  301.     
  302.     if (sLimit)
  303.     {
  304.         for (i=0; i<sLimit ;i++)
  305.         {
  306.             if (HICONS(sChild)[i] != NULL)
  307.             {
  308.                 GlobalFree (HICONS(sChild)[i]);
  309.                 HICONS(sChild)[i] = NULL;
  310.             }
  311.         }
  312.         SET_NUMICONS (sChild, 0);
  313.     }
  314. }
  315.  
  316.  
  317.  
  318.  
  319. //////////////////////////////////////////////////////////////////////////
  320. // SetupIconHandles - takes the active window, gets the icon filenames
  321. // from the listbox, loads those icons into memory in an array kept
  322. // in the animStruct.
  323. //////////////////////////////////////////////////////////////////////////
  324.  
  325. VOID WINAPI SetupIconHandles (HWND hwnd)
  326. {
  327.     short    sChild, sLimit, i;
  328.     HWND     hwndList;
  329.     HICON *  phIcons;
  330.     char     szlistbox[MAX_FILE_SIZE];
  331.  
  332.     if (!IsWindow(hwnd)) return;
  333.  
  334.     sChild = WINDOWNUM(hwnd);
  335.     hwndList = HWNDLIST(hwnd);
  336.  
  337.     SET_NUMICONS (sChild, (short)ListBox_GetCount(hwndList));
  338.     
  339.     sLimit    = NUMICONS(sChild);
  340.     phIcons  = HICONS(sChild);
  341.  
  342.     for (i=0 ; i<sLimit ; i++)
  343.     {   
  344.         ListBox_GetText (hwndList,i,(LPSTR)szlistbox);
  345.  
  346.         // If the user manually entered the filename in the
  347.         // .ANM file, and did not include a path, this condition
  348.         // takes care of it:
  349.         if (strrchr (szlistbox, '\\') == NULL)
  350.         {
  351.             char szDir[MAX_FILE_SIZE];
  352.  
  353.             getcwd (szDir, MAX_FILE_SIZE);
  354.  
  355.             if (szDir[strlen(szDir)-1] != '\\')
  356.             {
  357.                 strcat (szDir, "\\");
  358.             }
  359.             
  360.             strcat (szDir, szlistbox);
  361.  
  362.             phIcons[i] = ExtractIcon(_hInst, (LPSTR)szDir, 0);
  363.         }
  364.         else
  365.         {
  366.             phIcons[i] = ExtractIcon(_hInst, (LPSTR)szlistbox, 0);
  367.         }
  368.     }
  369.  
  370.     phIcons[sLimit] = NULL;
  371. }
  372.  
  373.  
  374.  
  375. //////////////////////////////////////////////////////////////////////////
  376. // DeleteCurSel - takes the selected files in the listbox, and
  377. // deletes them.
  378. //////////////////////////////////////////////////////////////////////////
  379.  
  380. BOOL WINAPI DeleteCurSel (HWND hwnd)
  381. {
  382.     short  sSel;
  383.     short  sChild;
  384.     short  sNumIcons;
  385.     HWND   hwndList;
  386.     short  i;
  387.     
  388.     if (!IsWindow(hwnd)) return FALSE;
  389.  
  390.     sChild = WINDOWNUM (hwnd);
  391.     hwndList = HWNDLIST (hwnd);
  392.     sNumIcons = NUMICONS (sChild);
  393.     
  394.     sSel = (short)ListBox_GetCurSel (hwndList);
  395.             
  396.     if (sSel == LB_ERR) 
  397.     {
  398.         return FALSE;
  399.     }
  400.  
  401.     for (i=sSel ; i<sNumIcons ; i++)
  402.     {
  403.         if (i == sSel)
  404.         {
  405.             GlobalFree (HICONS(sChild)[i]);
  406.         }
  407.         HICONS(sChild)[i] = HICONS(sChild)[i+1];
  408.     }
  409.     
  410.     SET_NUMICONS (sChild, --sNumIcons);
  411.  
  412.     ListBox_DeleteString (hwndList, sSel);
  413.     ListBox_SetCurSel (hwndList, sSel);
  414.  
  415.     return TRUE;
  416. }
  417.  
  418.  
  419.  
  420. //////////////////////////////////////////////////////////////////////////
  421. // GetWindowListbox - gets the active window, then looks to its first
  422. // extra window word for the handle to its listbox, and returns it.
  423. //////////////////////////////////////////////////////////////////////////
  424.  
  425. HWND WINAPI GetWindowListbox(VOID)
  426. {
  427.     return (HWND)(IsWindow(_hwndClient) ? 
  428.                                   HWNDLIST(MDI_GetActive(_hwndClient))
  429.                                 : NULL);
  430. }
  431.  
  432.  
  433.  
  434. //////////////////////////////////////////////////////////////////////////
  435. // GetWindowNumber - looks to the second extra window word in the 
  436. // window data structure, and finds the number of the window, and
  437. // returns it.  The number is kept for data structure access purposes.
  438. //////////////////////////////////////////////////////////////////////////
  439.  
  440. short WINAPI GetWindowNumber(VOID)
  441. {
  442.     return (short)(IsWindow(_hwndClient) ? 
  443.                               WINDOWNUM(MDI_GetActive(_hwndClient))
  444.                             : -1);
  445. }
  446.  
  447.  
  448.  
  449. //////////////////////////////////////////////////////////////////////////
  450. // CheckForDoubles - Just ensures that nobody tries to set up two 
  451. // animations on one running application.
  452. //////////////////////////////////////////////////////////////////////////
  453.  
  454. BOOL WINAPI CheckForDoubles (HWND hwnd)
  455. {
  456.     int  i;
  457.     BOOL result = FALSE;
  458.  
  459.     for (i=0 ; i<MAXANIMATIONS ; i++)
  460.     {
  461.         if (HWNDANIM(i)!=NULL)
  462.         {
  463.             if (HWNDTARGET(i) == hwnd)
  464.             {
  465.                 result = TRUE;
  466.             }
  467.         }
  468.     }
  469.  
  470.     return result;
  471. }
  472.  
  473.  
  474.  
  475. //////////////////////////////////////////////////////////////////////////
  476. // MESSAGE - just loads the appropriate string via the string ID value,
  477. // and displays it in the form of an error message box.
  478. //////////////////////////////////////////////////////////////////////////
  479.  
  480. VOID WINAPI MESSAGE (WORD wStringID)
  481. {
  482.     char szString[96];
  483.     LoadStr (wStringID,szString);
  484.     MessageBox (NULL, (LPSTR)szString, (LPSTR)_szAppName,
  485.                 MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
  486. }
  487.  
  488.  
  489.  
  490. //////////////////////////////////////////////////////////////////////////
  491. // GetTextWidth() - Gets the height of the string in the DC which
  492. // already has the font selected into it.
  493. //////////////////////////////////////////////////////////////////////////
  494.  
  495. UINT WINAPI GetTextWidth (HDC hdc, LPSTR lp)
  496. {
  497.     return (UINT)LOWORD(GetTextExtent (hdc, lp, lstrlen(lp)));
  498. }
  499.  
  500.  
  501.  
  502. //////////////////////////////////////////////////////////////////////////
  503. // GetTextHeight() - Gets the height of the string in the DC which
  504. // already has the font selected into it.
  505. //////////////////////////////////////////////////////////////////////////
  506.  
  507. UINT WINAPI GetTextHeight (HDC hdc, LPSTR lp)
  508. {
  509.     return (UINT)HIWORD(GetTextExtent (hdc, lp, lstrlen(lp)));
  510. }
  511.  
  512.  
  513.  
  514. //////////////////////////////////////////////////////////////////////////
  515. // GetANSITextHeight() - returns the height including leading to the
  516. // caller.
  517. //////////////////////////////////////////////////////////////////////////
  518.  
  519. UINT WINAPI GetANSITextHeight(VOID)
  520. {
  521.     TEXTMETRIC tm;
  522.     HDC hdc = GetDC (NULL);
  523.     HFONT hold = SelectFont (hdc, GetStockFont(ANSI_VAR_FONT));
  524.  
  525.     if (!hold) return 0;
  526.  
  527.     GetTextMetrics (hdc, &tm);
  528.     SelectFont (hdc, hold);
  529.     ReleaseDC (NULL, hdc);
  530.     return (UINT)(tm.tmHeight + tm.tmExternalLeading);
  531. }
  532.  
  533.  
  534.  
  535. //////////////////////////////////////////////////////////////////////////
  536. // NotifyProc() - Everytime TOOLHELP figures out that a task is 
  537. // exiting or starting, it notifies us via this callback function.
  538. // We immediately post the message to get the condition into the queue 
  539. // of a window. 
  540. //////////////////////////////////////////////////////////////////////////
  541.  
  542. BOOL _export CALLBACK NotifyProc (WORD wID, DWORD dwData)
  543. {
  544.     switch (wID)
  545.     {
  546.         case NFY_EXITTASK:
  547.         {
  548.             PostMessage (_hwndFrame, WM_COMMAND, IDN_EXITTASK, 0L);
  549.             break;
  550.         }
  551.  
  552.         case NFY_STARTTASK:
  553.         {
  554.             PostMessage (_hwndFrame, WM_COMMAND, IDN_NEWTASK, 0L);
  555.             break;
  556.         }
  557.  
  558.         default:
  559.             return FALSE;
  560.     }
  561.     return TRUE;
  562. }
  563.  
  564.  
  565.  
  566.  
  567. ///////////////////////////////////////////////////////////////////
  568. // ParseCmdLine() takes the command line for animator and parses 
  569. // it to find which files to initially open, and opens them.
  570. ///////////////////////////////////////////////////////////////////
  571.  
  572. VOID NEAR PASCAL ParseCmdLine (LPSTR lpszCmdLine)
  573. {
  574.     LPSTR   lpszCur = lpszCmdLine;
  575.     char    szFileName[MAX_FILE_SIZE];
  576.     short   i = 0;    
  577.     
  578.     AnsiUpper (lpszCmdLine);
  579.  
  580.     while (*lpszCur)
  581.     {
  582.         while (*lpszCur && *lpszCur != ' ')
  583.         {
  584.             szFileName[i++] = *lpszCur++;
  585.         }
  586.  
  587.         szFileName[i] = '\0';
  588.  
  589.         if (!GetPathIfNoPath ((LPSTR)szFileName))
  590.         {
  591.             MESSAGE (IDS_InvalidScript);
  592.         }
  593.         else
  594.         {
  595.             OpenIconsInFile (szFileName);
  596.         }
  597.  
  598.         if (*lpszCur) 
  599.         {
  600.             lpszCur++;  // kill leading blank character.
  601.         }
  602.  
  603.         i = 0;
  604.     }
  605. }
  606.